﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Reflection;

namespace AcesHigh.GUI
{
    public partial class MainWindow : Form
    {
        AboutBox1 aboutBox;

        List<TableDeckPanel> TableDeckPanels;
        List<PictureBox> deckList;
        Deck deck;

        private Image emptyDeckImage;
        private Image deckImage;
        private int discarded;
        private bool gameRunning = false;

        public MainWindow()
        {
            InitializeComponent();
            setupBoard();
            addHandlers();
        }


        public void addHandlers()
        {
            this.FormClosing += new FormClosingEventHandler(MainWindow_FormClosing);
        }

        public void InitTableCardPanels()
        {
            TableDeckPanels = new List<TableDeckPanel>(4);

            int xPos = 180;
            int yPos = deckPanel.Location.Y;

            TableDeckPanel cardPanel;
            for (int i = 0; i < 4; i++)
            {
                cardPanel = new TableDeckPanel();
                cardPanel.Location = new Point(xPos, yPos);
                cardPanel.CardClicked += new CardClickedEvent(cardClicked);
                panel1.Controls.Add(cardPanel);
                TableDeckPanels.Add(cardPanel);
                xPos += 100;
            }
         
            
        }

        public void createCardDeckImages()
        {
            
            int top = 3;
            int left = 0;
           

            for (int i = 0; i < 51; i++)
            {
                PictureBox pb = createCardPictureBox(left, top);
                deckList.Add(pb);
                this.deckPanel.Controls.Add(pb);
                pb.BringToFront();
                top += 3;
            }
            deckList[deckList.Count-1].DoubleClick += new EventHandler(Deck_DoubleClick);
        }

        public PictureBox createCardPictureBox(int left, int top) 
        {
            PictureBox pb = new PictureBox();
            pb.Location = new System.Drawing.Point(left, top);
            pb.Size = new System.Drawing.Size(72, 96);
            pb.TabIndex = 0;
            pb.TabStop = false;
            pb.Image = deckImage;
            pb.Focus();
            return pb;
        }

        public void Deck_DoubleClick(Object obj, EventArgs args)
        {
            Deal();
            if (deckList.Count == 0)
            {
                PictureBox empty = new PictureBox();
                empty.Size = new Size(72, 96);
                empty.Image = emptyDeckImage;
                deckPanel.Controls.Add(empty);
            }
            checkNoMoreMoves();
            
        }

        void Deal()
        {
            removeCardsFromDeck(4);

            if (deckList.Count > 0) {
                deckList[deckList.Count - 1].DoubleClick += new EventHandler(Deck_DoubleClick);
            }

            PictureCard picCard;
            Card card;
            foreach(TableDeckPanel cardPanel in TableDeckPanels)
            {
                card = deck.dealCard();
                picCard = new PictureCard(card, CardImagePathBuilder.getCardImagePath(card));
                picCard.SizeMode = PictureBoxSizeMode.AutoSize;
                cardPanel.addCard(picCard);
            }
        }

        void removeCardsFromDeck(int number)
        {
            for (int i = 0; i < number; i++)
            {
                if (deckList.Count > 0)
                {
                    deckPanel.Controls.Remove(deckList[deckList.Count - 1]);
                    deckList.RemoveAt(deckList.Count - 1);
                }
            }
        }

        private String GetImagePath()
        {
            return Application.StartupPath + "\\image";
        }

        internal void cardClicked(TableDeckPanel cardPanel, PictureCard card)
        {
            // check if card can be discarded
            if (canBeDiscarded(card))
            {
                discardCard(cardPanel, card);
            }
            else
            {
                moveToEmpty(cardPanel, card);
            }
            if (discarded == 48)
            {
                endGame();
                MessageBox.Show("Congratulations. You win", AssemblyInfo.AssemblyTitle);
                
            }
            checkNoMoreMoves();
        }

        private void checkNoMoreMoves()
        {
            // check if moves can be made
            if (!moveAvailable())
            {
                endGame();
                MessageBox.Show("Sorry. No more moves available.", AssemblyInfo.AssemblyTitle);

            }
        }
        private void endGame()
        {
            gameRunning = false;
        }

        private bool canBeDiscarded(PictureCard card)
        {
            foreach (TableDeckPanel cardPanel in TableDeckPanels)
            {
                if (card.IsLowerValue(cardPanel.TopCard)) return true;
            }

            return false;
        }

        private void moveToEmpty(TableDeckPanel sourceCardPanel, PictureCard card)
        {
            foreach (TableDeckPanel targetCardPanel in TableDeckPanels)
            {
                if (targetCardPanel.IsEmpty)
                {
                    sourceCardPanel.removeTopCard();
                    targetCardPanel.addCard(card);
                    break;
                }
            }
        }

        private bool moveAvailable()
        {
            if (deckList.Count > 0) return true;

            PictureCard testCard;
            foreach(TableDeckPanel testCardPanel in TableDeckPanels)
            {
                testCard = testCardPanel.TopCard;
                foreach (TableDeckPanel cardPanel in TableDeckPanels)
                {
                    if (testCard.IsLowerValue(cardPanel.TopCard)) return true;
                }
            }
            return false;
        }

        private void discardedPanel_DragEnter(Object sender, DragEventArgs args)
        {

            if (args.Data.GetDataPresent(typeof(TableDeckPanel)))
            {
                TableDeckPanel cp = (TableDeckPanel)args.Data.GetData(typeof(TableDeckPanel));
                PictureCard c = cp.TopCard;
                if (canBeDiscarded(c))
                {
                    args.Effect = DragDropEffects.Move;
                }
                else
                {
                    args.Effect = DragDropEffects.None;
                }
            }
            else
            {
                args.Effect = DragDropEffects.None;
            }
        }

        private void discardedPanel_DragDrop(Object sender, DragEventArgs args)
        {
            TableDeckPanel cp = (TableDeckPanel)args.Data.GetData(typeof(TableDeckPanel));

            PictureCard c = cp.TopCard;
            if (canBeDiscarded(c))
            {
                discardCard(cp, c);
            }
        }

        private void discardCard(TableDeckPanel cardPanel, PictureCard card)
        {
            cardPanel.removeTopCard();
            homepicturebox.Image = new Bitmap(card.Image);
            discarded++;
        }


        private void MainWindow_FormClosing(Object obj, CancelEventArgs args)
        {
            if (gameRunning && MessageBox.Show("Do you want to exit this game?", AssemblyInfo.AssemblyTitle,
                                        MessageBoxButtons.OKCancel) == DialogResult.Cancel)
            {
                args.Cancel = true;
            }

        }

        private void newGameToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            startGame();

        }

        private void startGame()
        {
            if (!gameRunning ||
                (gameRunning && MessageBox.Show("Do you wish to start a new game?", AssemblyInfo.AssemblyTitle,
                                    MessageBoxButtons.OKCancel) == DialogResult.OK))
            {
                setupBoard();
                deck = new Deck(GetImagePath());
                createCardDeckImages();
                discarded = 0;
                Deal();
                gameRunning = true;
            }
        }

        private void createEmptyDeck()
        {
            deckImage = new Bitmap(GetImagePath() + "\\b2fv.png");
            PictureBox pb = createCardPictureBox(0, 0);
            deckList = new List<PictureBox>();
            deckList.Add(pb);
            this.deckPanel.Controls.Add(pb);
            pb.BringToFront();
            
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (aboutBox == null)
            {
                aboutBox = new AboutBox1();
            }
            aboutBox.ShowDialog(this);
        }

        private void setupBoard()
        {
            initializeBoard();
            createEmptyDeck();
            InitTableCardPanels();
            emptyDeckImage = new Bitmap(Utility.getImagePath() + "\\NoCard.gif");
            homepicturebox.Image = emptyDeckImage;
        }

        private void dealMenuItem1_Click(object sender, EventArgs e)
        {
            if (!gameRunning)
            {
                startGame();
            }
            else
            {
                if (deckList.Count > 0)
                {
                    Deck_DoubleClick(sender, e);
                }
            }
                
        }
  
    }
}
